'''
--coding:utf-8--
@Author:丁一
@File:Base.py
@Project:python files
'''
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from Common.database import Database
from selenium.webdriver.support.select import Select
import time


def open_brower(brower: str):
    '''
    打开游览器函数
    :param brower: 具体传的浏览器名称，名称为chrome、firefox、edge
    :return:
    '''
    if brower.lower() == 'chrome':
        return webdriver.Chrome()
    elif brower.lower() == 'firefox':
        return webdriver.Firefox()
    elif brower.lower() == 'edge':
        return webdriver.Edge()
    else:
        print('您输入的浏览器有误，请输入“chrome”、“Firefox”、“edge”')


class Base(object):
    def __init__(self, brower: str):
        self.driver = open_brower(brower)
        self.database = Database()

    def open_url(self, url: str):
        '''
        打开网页
        :param url: 输入的域名，格式为"http://www.xxx.com/" or "https://www.xxx.com/"
        :return:
        '''
        try:
            # 判断输入的网址是否是 http://或者https://开头,是就直接打开,不是就在前面加上http://
            if url.startswith('http://') or url.startswith('https://'):  # 判断网页证书
                self.driver.get(url)
            else:
                url = "http://" + url
                self.driver.get(url)
        except Exception as e:
            print(f"网页打开失败,失败提示:{e}")
            print(f"输入网址是{url}")

    def find_element(self, locator: tuple, timeout=10):
        '''
        单个元素定位,成功返回元素,失败返回False
        :param locator: 定位器
        :param timeout:超时时间
        :return:
        '''
        try:
            return WebDriverWait(self.driver, timeout).until(EC.presence_of_element_located(locator))
        except Exception as e:
            print(f'未定位到元素{e}')
            return False

    def find_elements(self, locator: tuple, timeout=10):
        '''
        多个元素定位,定位成功返回元素列表,失败返回False
        :param locator: 定位器
        :param timeout: 超时时间
        :return:
        '''
        try:
            return WebDriverWait(self.driver, timeout).until(EC.presence_of_all_elements_located(locator))
        except Exception as e:
            print(f'未定位到元素{e}')
            return False

    def send_keys(self, locator: tuple, text: str, timeout=10):
        '''
        定位之后进行输入内容
        :param locator: 定位器
        :param text: 输入的文本信息
        :param timeout: 超时时间
        :return:
        '''
        ele = self.find_element(locator, timeout)  # 定位元素
        if ele is not False:
            ele.send_keys(str(text))  # 输入值
        else:
            print('元素定位失败,不能输入信息')

    def click(self, locator: tuple, timeout=10):
        '''
        根据输入元素进行点击
        :param locator:
        :param timeout:
        :return:
        '''
        ele = self.find_element(locator, timeout)  # 定位元素
        if ele is not False:
            ele.click()  # 点击
        else:
            print('元素定位失败,不能点击')

    def clear(self, locator: tuple, timeout=10):
        '''
        根据输入元素进行清空
        :param locator: 定位器
        :param timeout: 超时时间
        :return:
        '''
        ele = self.find_element(locator, timeout)  # 定位元素
        if ele is not False:
            ele.clear()  # 清空
        else:
            print('元素定位失败,不能清空')

    def is_seleted(self, locator: tuple, timeout=10):
        '''
        判断元素定位是否成功
        :param locator: 定位器
        :param timeout: 超时时间
        :return:
        '''
        ele = self.find_element(locator, timeout)
        if ele is not False:
            return ele.is_selected()
        else:
            print('元素定位失败')

    def scroll_bar(self, x, y):
        """
        滚动条方法封装
        :param x: 横向移动,x初始为0
        :param y: 纵向移动,y初始为0
        :return:
        """
        js = f"window.scrollTo({x},{y})"
        self.driver.execute_script(js)

    def get_element_text(self, locator: tuple, timeout=10):
        '''
        获取定位元素的文本
        :param locator:
        :param timeout:
        :return:
        '''
        ele = self.find_element(locator, timeout)
        if ele is not False:
            return ele.text
        else:
            return None

    def get_text_assert(self, expected, locator: tuple, timeout=10):
        '''
        获取文本信息进行断言
        :param expected: 预期结果
        :param locator: 定位器
        :param timeout: 超时时间
        :return:预期内容和实际内容一样返回True,否则返回False
        '''
        text_content = self.get_element_text(locator, timeout)
        if text_content is not None:
            if expected == text_content:
                print('断言成功')
                return True
            else:
                print('断言失败')
                return False
        else:
            return False

    def get_database_data_all(self, sql):
        '''
        获取数据库的数据
        @param sql: sql语句
        @return:
        '''
        try:
            data = self.database.get_all(sql)
        except Exception as e:
            print(f"从数据库-获取数据失败{e},sql语句:{sql}")
            return None
        else:
            return data

    def get_database_data_one(self, sql):
        '''
        获取数据库的一条数据
        @param sql: sql语句
        @return:
        '''
        try:
            data = self.database.get_one(sql)
        except Exception as e:
            print(f"从数据库-获取数据失败{e},sql语句:{sql}")
            return None
        else:
            return data

    def confirm(self):  # confirm弹窗
        my_confirm = self.driver.switch_to.alert
        my_confirm.accept()

    def login(self, username, password):
        '''
        前台登录
        @param username: 输入用户名
        @param password: 输入密码
        @return:
        '''
        user_ele = ('name', 'username')  # 用户名输入框
        password_ele = ('name', "password")  # 密码输出口
        login_ele = ("name", "submit")  # 登录按钮
        self.send_keys(user_ele, username)  # 输入账号
        self.send_keys(password_ele, password)  # 输入密码
        self.click(login_ele)  # 点击登录

    def backstage_login(self, username, password):
        '''
        后台登录
        @param username: 输入用户名
        @param password: 输入密码
        @return:
        '''
        user_locator = ('css selector', 'input[placeholder="请填写您注册的邮箱或手机"]')  # 用户名
        password_locator = ('css selector', 'input[placeholder="请输入密码"]')  # 密码
        login_locator = ('css selector', 'input[value="登 录"]')  # 登录按钮
        close_pop_up_ads_locator = ('css selector', 'span[onclick = "btnCancel(this)"]')  # 关闭弹窗按钮
        choose_login_methods = ('css selector', 'span[class ="btn-tab"]')  # 选择登录方式
        self.click(close_pop_up_ads_locator)  # 关闭广告弹窗
        self.click(choose_login_methods)  # 点击选择登录方式
        self.send_keys(user_locator, username)  # 输入用户名
        self.send_keys(password_locator, password)  # 输入密码
        self.click(login_locator)  # 点击登录

    def drop_down_box(self, country_address, value1, province_address, value2, city_address, value3, district_address,
                      value4):
        '''
        收货人信息下拉框
        @param country_address: 国家元素定位
        @param value1: 国家的value值
        @param province_address:省元素定位
        @param value2:省的value值
        @param city_address:城市元素定位
        @param value3:市的value值
        @param district_address:区元素定位
        @param value4:区的value值
        @return:
        '''
        ele = self.find_element(country_address)  # 定位国家选项元素
        Select(ele).select_by_value(value1)  # 选取值
        ele2 = self.find_element(province_address)  # 定位省选项元素
        Select(ele2).select_by_value(value2)  # 选取值
        time.sleep(3)  # 必须睡3秒否则定位不到下面元素
        ele3 = self.find_element(city_address)  # 定位市选项元素
        Select(ele3).select_by_value(value3)  # 选取值
        time.sleep(3)  # 必须睡3秒否则定位不到下面元素
        ele4 = self.find_element(district_address)  # 定位区选项元素
        Select(ele4).select_by_value(value4)  # 选取值

    def close_browser(self):  # 关闭浏览器
        self.driver.quit()


